package calpi.util;

import java.security.InvalidKeyException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Classe responsável pela criptografia dos dados do sistema
 * @author Sem iNick
 */
public final class Crypter {

    private static final String BASE_KEY = "2h5ik24j";

    private SecretKeySpec key;
    private Cipher crypter;

    private Crypter(String sKey)
            throws NoSuchAlgorithmException, NoSuchPaddingException {

        crypter = Cipher.getInstance("ARCFOUR/ECB/NoPadding");
        key = new SecretKeySpec(sKey.getBytes(), "ARCFOUR");
    }

    /**
     * Cria um instância do criptografador usando uma chave padrão
     * @return Objeto que descreve o criptografador ou null caso ocorra algum erro
     */
    public static Crypter getInstance() {
            

        return getInstance(BASE_KEY);
    }

    /**
     * Cria um instância do criptografador usando uma determinda chave
     * @return Objeto que descreve o criptografador ou null caso ocorra algum erro
     */
    public static Crypter getInstance(String stringKey) {

        try {
        
            return new Crypter(stringKey);
        } catch (Exception e) {}

        return null;
    }

    /**
     * Criptografa uma string usando o algorítmo MD5
     * @param toEncode String que será criptografada
     * @return Representação criptografada da string ou nulo caso exista algum erro
     */
    public static final String encodeMD5(String toEncode) {

        try {

            MessageDigest crypter = MessageDigest.getInstance("MD5");
            return new String(crypter.digest(toEncode.getBytes()));
        } catch (NoSuchAlgorithmException nsae) {}

        return null;
    }

    /**
     * Descriptografa um string usando um algorítimo padrão
     * @param enTexto Texto a ser descriptografado
     * @return String descriptografado
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public String decode(String enTexto)
            throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {


        crypter.init(Cipher.DECRYPT_MODE, key);
        return new String(crypter.doFinal(enTexto.getBytes()));
    }

    /**
     * Criptografa um string usando um algorítimo padrão
     * @param enTexto Texto a ser criptografado
     * @return String criptografado
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public String encode(String enTexto)
            throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {


        crypter.init(Cipher.ENCRYPT_MODE, key);
        return new String(crypter.doFinal(enTexto.getBytes()));
    }
}
